﻿#region references
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Linq;
using System.Web.UI;
using System.Web.Security;

/* Project dependencies */
using IcaGames.Objects;
using IcaGames.Database;
using IcaGames.Security;
using IcaGames.Database.ObjectManagement;
#endregion

public partial class Cart : System.Web.UI.Page
{
    #region public attributes

    public ShoppingCart _savedCart
    {
        set { ViewState["savedCart"] = value; }
        get
        {
            ShoppingCart ret = null;
            if (ViewState["savedCart"] != null)
                ret = (ShoppingCart)ViewState["savedCart"];
            return ret;
        }
    }

    public decimal totalPrice, totalSize;

    #endregion

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            /* First check if there is an existing shopping cart saved in the database */
            ShoppingCart cart = CheckSavedShoppingCart();
            List<Game> cartDataSource = new List<Game>();
            if (cart != null)
            {
                if (cart.CartId > 0)
                {
                    cart.Games = CartManagement.GetShoppingCartGames(cart.CartId);
                    _savedCart = new ShoppingCart();
                    _savedCart = cart;

                    cartDataSource = CheckSessionCart(cart);
                }
                else
                {
                    cartDataSource = CheckSessionCart(null);
                }
            }

            gvCart.DataSource = cartDataSource;
            gvCart.DataBind();

            if (cartDataSource != null)
            {
                if (Page.User.Identity.IsAuthenticated)
                {
                    /* Refresh the shopping cart on the masterpage */
                    decimal[] cartContents = CartManagement.RefreshShoppingCart(cartDataSource);
                    Session["cartPrice"] = cartContents;

                    LinkButton lbCartInfo = ((LoginView)Page.Master.FindControl("LoginView1")).FindControl("lbCartInfo") as LinkButton;
                    lbCartInfo.Text = cartContents[1] + " artikel(en) totaalprijs: € " + String.Format("{0:0,##}",
                    cartContents[0].ToString().Replace('.', ','));
                }
                else
                {
                    cartDataSource = CheckSessionCart(null);
                    if (cartDataSource != null)
                    {
                        if (cartDataSource.Count == 0)
                        {
                            btnClearCart.Visible = false; btnSaveOrder.Visible = false;
                        }
                        else
                        {
                            gvCart.DataSource = cartDataSource;
                            gvCart.DataBind();
                        }
                    }
                }
            }
            else
            {
                btnClearCart.Visible = false; btnSaveOrder.Visible = false;
            }
        }
    }

    /*
     * Function to check if there is a Session containing games for the shopping cart.
     * 
     * @param
     * cart: The shopping cart that was loaded from the database.
     */
    private List<Game> CheckSessionCart(ShoppingCart cart)
    {
        /* Now check if the user has anything in his Session */
        if (Session["cart"] != null)
        {
            ShoppingCart sessionCart = (ShoppingCart)Session["cart"];
            if (cart != null)
            {
                bool exists = false;

                foreach (Game g in sessionCart.Games)
                {
                    foreach (Game sg in cart.Games)
                    {
                        if (g.GameNr == sg.GameNr && g.Platform == sg.Platform)
                        {
                            sg.Amount++;
                            g.Amount = sg.Amount;
                            exists = true;
                            CartManagement.UpdateShoppingCartGame(cart.CartId, g);
                            break;
                        }
                    }
                    if (!exists)
                    {
                        cart.Games.Add(g);
                        exists = false;
                        CartManagement.SaveShoppingCartGame(cart.CartId, g);
                    }
                }
                Session["cart"] = null;
                _savedCart = cart;

                return cart.Games;
            }
            else { return sessionCart.Games; }
        }
        else 
        {
            if (cart != null) { return cart.Games; }
            else { return null; }
        }
    }

    /*
     * Function to check if a user that is logged in, allready has a saved shopping cart.
     */
    private ShoppingCart CheckSavedShoppingCart()
    {
        if (Page.User.Identity.IsAuthenticated)
        {
            CustomMembershipProvider provider = Membership.Provider as CustomMembershipProvider;
            int userId = provider.GetUserId(Page.User.Identity.Name);
            ShoppingCart c = CartManagement.GetShoppingCart(userId, "Nee");
            return c;
        }
        else
        {
            return null;
        }
    }

    /*
     * Function that is executed when the event RowDataBound is fired.
     * 
     */
    protected void gvCart_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Label lblGamePrice = e.Row.FindControl("lblGamePrice") as Label;
            Label lblGameSubTotalPrice = e.Row.FindControl("lblGameSubTotalPrice") as Label;
            Label lblGameAmount = e.Row.FindControl("lblGameAmount") as Label;
            Label lblGamePlatform = e.Row.FindControl("lblGamePlatform") as Label;
            Label lblGameSize = e.Row.FindControl("lblGameSize") as Label;
            ImageButton ibtnDelete = e.Row.FindControl("ibtnDelete") as ImageButton;
            ImageButton ibtnAdd = e.Row.FindControl("ibtnAdd") as ImageButton;
            LinkButton lbGameTitle = e.Row.FindControl("lbGameTitle") as LinkButton;

            /* Set lbGameTitle Click event and CommandArgument */
            if (lbGameTitle != null) { lbGameTitle.Click += ToGameDetails; }

            /* Set the total size of the selected games */
            if (lblGameSize != null &&
                lblGameAmount != null)
            {
                int totalSize = int.Parse(lblGameSize.Text) * int.Parse(lblGameAmount.Text);
                lblGameSize.Text = totalSize.ToString() + " (MB)";
                this.totalSize += totalSize;
            }

            /* Set ibtnDelete Click event and CommandArgument */
            if (ibtnDelete != null)
            {
                ibtnDelete.CommandArgument = e.Row.RowIndex.ToString();
                ibtnDelete.Click += RemoveGame;
            }

            /* Set ibtnAdd Click event and CommandArgument */
            if (ibtnAdd != null)
            {
                ibtnAdd.CommandArgument = e.Row.RowIndex.ToString();
                ibtnAdd.Click += AddGame;
            }

            /* Calculate the subtotal of the price */
            if (lblGameSubTotalPrice != null &&
                lblGameAmount != null &&
                lblGamePrice != null)
            {
                decimal subTotalPrice = decimal.Parse(lblGamePrice.Text) * int.Parse(lblGameAmount.Text);
                lblGameSubTotalPrice.Text = "€ " + String.Format("{0:0,##}", subTotalPrice.ToString().Replace('.', ','));
                totalPrice += subTotalPrice;
            }

            /* Set the correct format for the Game price */
            if (lblGamePrice != null) { lblGamePrice.Text = "€ " + String.Format("{0:0,##}", lblGamePrice.Text.Replace('.', ',')); }

            /* Set the description for the Game Platform */
            if (lblGamePlatform != null)
            {
                Platform pf = PlatformValue.GetPlatform(lblGamePlatform.Text);
                lblGamePlatform.Text = PlatformDescription.GetDescription(pf);
            }
        }
        else if (e.Row.RowType == DataControlRowType.Footer)
        {
            e.Row.Cells[4].Text = "€ " + String.Format("{0:0,##}", totalPrice.ToString().Replace('.', ','));
            lblTotalPrice.Text = "€ " + String.Format("{0:0,##}", totalPrice.ToString().Replace('.', ','));
            e.Row.Cells[5].Text = totalSize.ToString() + " (MB)";
            if (totalSize > 10000) { e.Row.Cells[5].ForeColor = System.Drawing.Color.Red; }
            else { e.Row.Cells[5].ForeColor = System.Drawing.Color.Green; }
        }
    }

    /*
     * Function that add's a selected game to the shopping cart.
     */
    protected void AddGame(object sender, ImageClickEventArgs e)
    {
        ImageButton ibtn = sender as ImageButton;
        GridViewRow row = null;

        if (ibtn != null) { row = gvCart.Rows[int.Parse(ibtn.CommandArgument)]; }
        if (row != null)
        {
            string[] param = ((LinkButton)row.FindControl("lbGameTitle")).CommandArgument.Split('_');
            Platform pf = PlatformValue.GetPlatform(param[1]);
            ShoppingCart c = new ShoppingCart();
            Game g = new Game(); GameManagement.GetGame(int.Parse(param[0]), g, param[1]);

            if (Session["cart"] != null)
            {
                c = (ShoppingCart)Session["cart"];
                c.Games = CartManagement.AddGameToCart(c.CartId, c.Games, g);
                Session["cart"] = c;
            }
            else
            {
                c = (ShoppingCart)ViewState["savedCart"];
                c.Games = CartManagement.AddGameToCart(c.CartId, c.Games, g);
                _savedCart = c;
            }

            gvCart.DataSource = c.Games;
            gvCart.DataBind();

            if (Page.User.Identity.IsAuthenticated)
            {
                /* Refresh the shopping cart on the masterpage */
                decimal[] cartContents = CartManagement.RefreshShoppingCart(c.Games);
                Session["cartPrice"] = cartContents;

                LinkButton lbCartInfo = ((LoginView)Page.Master.FindControl("LoginView1")).FindControl("lbCartInfo") as LinkButton;
                lbCartInfo.Text = cartContents[1] + " artikel(en) totaalprijs: € " + String.Format("{0:0,##}",
                cartContents[0].ToString().Replace('.', ','));
            }
        }
    }

    /*
     * Function that deletes a selected game from the shopping cart.
     */
    protected void RemoveGame(object sender, ImageClickEventArgs e)
    {
        ImageButton ibtn = sender as ImageButton;
        GridViewRow row = null;

        if (ibtn != null) { row = gvCart.Rows[int.Parse(ibtn.CommandArgument)]; }
        if (row != null)
        {
            string[] param = ((LinkButton)row.FindControl("lbGameTitle")).CommandArgument.Split('_');
            Platform pf = PlatformValue.GetPlatform(param[1]);

            /* Check if a Session exists that holds a shopping cart */
            ShoppingCart c = new ShoppingCart();
            if (Session["cart"] != null)
            {
                c = (ShoppingCart)Session["cart"];
                c.Games = CartManagement.DeleteGameFromCart(c.CartId, c.Games, int.Parse(param[0]), pf);
                Session["cart"] = c;
            }
            else
            {
                c = (ShoppingCart)ViewState["savedCart"];
                c.Games = CartManagement.DeleteGameFromCart(c.CartId, c.Games, int.Parse(param[0]), pf);
                _savedCart = c;
            }

            if (c.Games.Count == 0) { btnClearCart.Visible = false; btnSaveOrder.Visible = false; }

            gvCart.DataSource = c.Games;
            gvCart.DataBind();

            if (Page.User.Identity.IsAuthenticated)
            {
                /* Refresh the shopping cart on the masterpage */
                decimal[] cartContents = CartManagement.RefreshShoppingCart(c.Games);
                Session["cartPrice"] = cartContents;

                LinkButton lbCartInfo = ((LoginView)Page.Master.FindControl("LoginView1")).FindControl("lbCartInfo") as LinkButton;
                lbCartInfo.Text = cartContents[1] + " artikel(en) totaalprijs: € " + String.Format("{0:0,##}",
                cartContents[0].ToString().Replace('.', ','));
            }
        }
    }

    /*
     * Function that redirect's the user to the game information page of the selected game.
     */
    protected void ToGameDetails(object sender, EventArgs e)
    {
        string queryString = ((LinkButton)sender).CommandArgument;
        Response.Redirect("~/GameDetails.aspx?g=" + queryString);
    }

    /*
     * Function to clear the shopping cart.
     */
    protected void ClearCart(object sender, EventArgs e)
    {
        Session["cart"] = null;
        gvCart.DataSource = null;
        gvCart.DataBind();
        btnClearCart.Visible = false;
        btnSaveOrder.Visible = false;
    }

    /*
     * Function to pay the selected order.
     */
    protected void SaveShoppingCart(object sender, EventArgs e)
    {
        if (Page.User.Identity.IsAuthenticated)
        {
            pnlRegister.Visible = false;
            pnlCart.Visible = false;
            btnClearCart.Visible = false;
            btnSaveOrder.Visible = false;
            pnlPayOrder.Visible = true;
            pnlErrors.Visible = false;

            /* Save the shopping cart into the database */
            SaveCart("Nee");
        }
        else
        {
            pnlRegister.Visible = true;
            pnlCart.Visible = false;
            pnlPayOrder.Visible = false;
            pnlErrors.Visible = false;
        }
    }

    /*
     * Function to save the shopping cart into the database.
     * 
     * @param
     * orderPaid: Check if the order has been paid yet or not.
     */
    private void SaveCart(string orderPaid)
    {
        if (orderPaid.Equals("Ja"))
        {
            CartManagement.UpdateShoppingCart(_savedCart.CartId, "Ja");
            Response.Redirect("~/Account.aspx");
        }
        else
        {
            if (Session["cart"] != null)
            {
                CustomMembershipProvider provider = Membership.Provider as CustomMembershipProvider;
                int userId = provider.GetUserId(Page.User.Identity.Name);
                ShoppingCart c = (ShoppingCart)Session["cart"];
                int cartId = CartManagement.SaveShoppingCart(userId, c.Games);

                if (cartId == -1)
                {
                    /* Set the error message using the ErrorTable UserControl */
                    ucErrors._labelText = "Er is een fout opgetreden bij het opslaan van de winkelwagen. Probeer het nogmaals.";
                    ucErrors._pnlVisibility = true;
                    pnlCart.Visible = false;
                    pnlErrors.Visible = true;
                }
                else
                {
                    c.CartId = cartId;
                    _savedCart = c;
                    Session["cart"] = null;
                }
            }
        }
    }

    /*
     * Function that is executed when the LinkButton lbBackToCart is clicked.
     * 
     * Redirect's the user back to his/her shopping cart.
     */
    protected void BackToCart(object sender, EventArgs e)
    {
        pnlCart.Visible = true;
        pnlRegister.Visible = false;
    }

    /*
     * Function that handles the payment of the shopping cart.
     */
    protected void DoPayment(object sender, EventArgs e)
    {
        if (Page.User.Identity.IsAuthenticated)
        {
            SaveCart("Ja");
        }
        else
        {
            pnlRegister.Visible = true;
            pnlCart.Visible = false;
            pnlPayOrder.Visible = false;
        }
    }
}
